5 // Copyright (c) 2020 Apple Inc. All rights reserved.
8 #import <XCTest/XCTest.h>
10 #include "mDNSEmbeddedAPI.h"
11 #if MDNSRESPONDER_SUPPORTS(APPLE, DNSSECv2)
13 typedef struct test_struct_t {
18 @interface ListTMethodsTest : XCTestCase
22 @implementation ListTMethodsTest
24 - (void)testListInitAndUninit{
27 list_init(&list, sizeof(test_struct_t));
28 XCTAssertEqual(list.head_ptr, &list.head, @"list.head_ptr should point to list.head");
29 XCTAssertEqual(list.tail_ptr, &list.tail, @"list.tail_ptr should point to list.tail");
30 XCTAssertEqual(list.head_ptr->next, list.tail_ptr, @"The next node of head should be tail");
31 XCTAssertEqual(list.tail_ptr->prev, list.head_ptr, @"The previous node of tail should be head");
32 XCTAssertEqual(list.data_size, sizeof(test_struct_t), @"The data size should be sizeof(test_struct_t)");
35 XCTAssertEqual(list.data_size, 0, @"The data size should be 0");
36 XCTAssertNil((__bridge id)list.head.next, @"The next node of head should be NULL");
37 XCTAssertNil((__bridge id)list.tail.prev, @"The previous node of tail should be NULL");
38 XCTAssertNil((__bridge id)list.head_ptr, @"The head pointer should point to NULL");
39 XCTAssertNil((__bridge id)list.tail_ptr, @"The tail pointer should point to NULL");
42 - (void)testListGeneralOperation{
47 test_struct_t *append_node_data_1, *append_node_data_2, *prepend_node_data_1, *prepend_node_data_2;
48 list_node_t *first_node, *second_node, *third_node, *fourth_node;
51 list_init(&list, sizeof(test_struct_t));
53 // Get first and last for empty list
54 XCTAssertNil((__bridge id)list_get_first(&list));
55 XCTAssertNil((__bridge id)list_get_last(&list));
58 error = list_append_uinitialized(&list, sizeof(test_struct_t), (void **)&append_node_data_1);
59 XCTAssertEqual(error, mStatus_NoError, @"list_append_uinitialized failed; error_description='%s'", mStatusDescription(error));
60 first_node = list.head_ptr->next;
61 XCTAssertEqual(first_node->prev, list.head_ptr, @"The first node should point to head");
62 XCTAssertEqual(first_node->next, list.tail_ptr, @"The next of first node should point to tail");
63 XCTAssertEqual(list.tail_ptr->prev, first_node, @"The previous of tail should point to first node");
64 XCTAssertEqual((void *)first_node->data, (void *)append_node_data_1, @"The data field should be equal to the returned data pointer");
67 XCTAssertEqual(list_get_first(&list), first_node);
68 XCTAssertEqual(list_get_last(&list), first_node);
71 error = list_append_uinitialized(&list, sizeof(test_struct_t) - 1, (void **)&append_node_data_2);
72 XCTAssertEqual(error, mStatus_BadParamErr, @"List should not add new node since the type of embedded data does not match");
75 empty = list_empty(&list);
76 XCTAssertFalse(empty, @"List should not be empty");
79 count = list_count_node(&list);
80 XCTAssertEqual(count, 1, @"There should be only 1 node");
82 // Append 2nd succeeds
83 error = list_append_uinitialized(&list, sizeof(test_struct_t), (void **)&append_node_data_2);
84 XCTAssertEqual(error, mStatus_NoError, @"list_append_uinitialized failed; error_description='%s'", mStatusDescription(error));
85 second_node = list.tail_ptr->prev;
86 XCTAssertEqual(first_node->next, second_node);
87 XCTAssertEqual(first_node->prev, list.head_ptr);
88 XCTAssertEqual(first_node->next, second_node);
89 XCTAssertEqual(second_node->next, list.tail_ptr);
90 XCTAssertEqual(second_node->prev, first_node);
91 XCTAssertEqual((void *)second_node->data, (void *)append_node_data_2);
94 count = list_count_node(&list);
95 XCTAssertEqual(count, 2);
98 XCTAssertEqual(list_get_first(&list), first_node);
99 XCTAssertEqual(list_get_last(&list), second_node);
101 // Prepend 3rd succeeds
102 error = list_prepend_uinitialized(&list, sizeof(test_struct_t), (void **)&prepend_node_data_1);
103 XCTAssertEqual(error, mStatus_NoError);
104 third_node = list.head_ptr->next;
105 XCTAssertEqual(third_node->next, first_node);
106 XCTAssertEqual(third_node->prev, list.head_ptr);
107 XCTAssertEqual(first_node->prev, third_node);
108 XCTAssertEqual((void *)third_node->data, (void *)prepend_node_data_1);
111 count = list_count_node(&list);
112 XCTAssertEqual(count, 3);
114 // Get first and last
115 XCTAssertEqual(list_get_first(&list), third_node);
116 XCTAssertEqual(list_get_last(&list), second_node);
119 error = list_prepend_uinitialized(&list, sizeof(test_struct_t) - 1, (void **)&prepend_node_data_2);
120 XCTAssertEqual(error, mStatus_BadParamErr);
122 // Preopend 4th succeeds
123 error = list_prepend_uinitialized(&list, sizeof(test_struct_t), (void **)&prepend_node_data_2);
124 XCTAssertEqual(error, mStatus_NoError);
125 fourth_node = list.head_ptr->next;
126 XCTAssertEqual(fourth_node->next, third_node);
127 XCTAssertEqual(fourth_node->prev, list.head_ptr);
128 XCTAssertEqual(third_node->prev, fourth_node);
129 XCTAssertEqual((void *)fourth_node->data, (void *)prepend_node_data_2);
132 count = list_count_node(&list);
133 XCTAssertEqual(count, 4);
135 // Get first and last
136 XCTAssertEqual(list_get_first(&list), fourth_node);
137 XCTAssertEqual(list_get_last(&list), second_node);
140 for (list_node_t *node = list_get_first(&list); !list_has_ended(&list, node); node = list_next(node)) {
141 if (node == first_node) {
142 XCTAssertEqual((void *)node->data, (void *)append_node_data_1);
143 } else if (node == second_node) {
144 XCTAssertEqual((void *)node->data, (void *)append_node_data_2);
145 } else if (node == third_node) {
146 XCTAssertEqual((void *)node->data, (void *)prepend_node_data_1);
147 } else if (node == fourth_node) {
148 XCTAssertEqual((void *)node->data, (void *)prepend_node_data_2);
150 XCTAssertTrue(mDNSfalse, @"Unknown node added into the list");
154 // Delete one node with node pointer
155 list_node_delete(first_node);
156 XCTAssertEqual(third_node->next, second_node);
157 XCTAssertEqual(third_node->prev, fourth_node);
158 XCTAssertEqual(second_node->prev, third_node);
159 XCTAssertEqual(list_count_node(&list), 3);
160 XCTAssertFalse(list_empty(&list));
162 // Delete one node with data pointer that exists
163 error = list_delete_node_with_data_ptr(&list, prepend_node_data_2);
164 XCTAssertEqual(error, mStatus_NoError);
165 XCTAssertEqual(list_get_first(&list), third_node);
166 XCTAssertEqual(list_get_last(&list), second_node);
167 XCTAssertEqual(third_node->next, second_node);
168 XCTAssertEqual(third_node->prev, list.head_ptr);
169 XCTAssertEqual(second_node->next, list.tail_ptr);
170 XCTAssertEqual(list_count_node(&list), 2);
171 XCTAssertFalse(list_empty(&list));
173 // Delete one node with data pointer that does not exist
174 error = list_delete_node_with_data_ptr(&list, prepend_node_data_2 + 1);
175 XCTAssertEqual(error, mStatus_NoSuchKey);
176 XCTAssertEqual(list_get_first(&list), third_node);
177 XCTAssertEqual(list_get_last(&list), second_node);
178 XCTAssertEqual(third_node->next, second_node);
179 XCTAssertEqual(third_node->prev, list.head_ptr);
180 XCTAssertEqual(second_node->next, list.tail_ptr);
181 XCTAssertEqual(list_count_node(&list), 2);
182 XCTAssertFalse(list_empty(&list));
184 // Delete all the nodes
185 list_node_delete_all(&list);
188 count = list_count_node(&list);
189 XCTAssertEqual(count, 0);
192 empty = list_empty(&list);
193 XCTAssertTrue(empty);
195 // Iterate through the empty list
196 for (list_node_t *node = list_get_first(&list); !list_has_ended(&list, node); node = list_next(node)) {
197 XCTAssertFalse(mDNStrue, @"Should never excute this line if the line is empty");
200 // uninitialize the list
202 XCTAssertEqual(list.data_size, 0);
203 XCTAssertNil((__bridge id)list.head.next);
204 XCTAssertNil((__bridge id)list.tail.prev);
205 XCTAssertNil((__bridge id)list.head_ptr);
206 XCTAssertNil((__bridge id)list.tail_ptr);
210 #endif // MDNSRESPONDER_SUPPORTS(APPLE, DNSSECv2)